package org.wx.io.netty.rpc.client;

import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.DefaultEventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.wx.io.netty.rpc.intface.Car;
import org.wx.io.netty.rpc.protocol.MyContent;
import org.wx.io.netty.rpc.protocol.MyHeader;
import org.wx.io.netty.rpc.protocol.PackMsg;
import org.wx.io.netty.rpc.proxy.RpcProxy;

import java.util.concurrent.CompletableFuture;

/**
 * @description:
 * @author: wangxun
 * @createDate: 2021/2/23
 * @version: 1.0
 */
@Slf4j
public class RpcClientHandler extends SimpleChannelInboundHandler<PackMsg> {

    /*
       加入异步线程池去处理业务等待问题，不让Socket线程去等待执行的结果
        */
    static DefaultEventLoopGroup defaultEventLoopGroup =  new DefaultEventLoopGroup(16);


    @Override
    protected void channelRead0(ChannelHandlerContext ctx, PackMsg msg) throws Exception {
        log.info("client 接受到返回{}",msg);
        MyHeader myHeader = msg.getMyHeader();
        long requestId = myHeader.getRequestId();

        if(0x99999999 == myHeader.getFlag()){ //没有代理对象
            log.error("没有代理对象...requestId:{}",requestId);
        }else if(0X14141424 == myHeader.getFlag()){
            MyContent myContent = msg.getMyContent();
            log.error("正确返回对象...res:{}",myContent.getRes());
            CompletableFuture completableFuture = RpcClient.futureMap.get(requestId);
            // 设置返回值
            if(completableFuture != null){
                completableFuture.complete(myContent.getRes());
            }else {
                log.error("RpcClient.futureMap 没有对应的异步操作");
            }
        }
        // 删除对应的异步等待
        RpcClient.futureMap.remove(requestId);

    }

    /**
     * 激活之后就去调用
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("channel 激活，发送数据");

        // 利用业务线程池去执行业务处理的异步回调，让socket线程继续监听读写事件
        defaultEventLoopGroup.submit(()->{
            Car car = null;
            try {
                car = RpcProxy.proxyGet(Car.class,ctx);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 这才会去真正调用代理handler的invoke方法
            String res = car.come(9 * 1000, 5.0);
            log.info("调用方法的结果是:{}",res);
        });

    }
}
